package com.governtalk.backend.service.impl;

import com.governtalk.backend.dto.CollectionDto;
import com.governtalk.backend.entity.Collection;
import com.governtalk.backend.entity.User;
import com.governtalk.backend.repository.CollectionRepository;
import com.governtalk.backend.repository.UserRepository;
import com.governtalk.backend.service.CollectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@Transactional
public class CollectionServiceImpl implements CollectionService {
    
    @Autowired
    private CollectionRepository collectionRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public CollectionDto addCollection(CollectionDto collectionDto) {
        User user = userRepository.findById(collectionDto.getUserId())
                .orElseGet(() -> {
                    // 如果用户不存在，创建一个默认用户
                    User defaultUser = User.builder()
                            .id(collectionDto.getUserId())
                            .username("user" + collectionDto.getUserId())
                            .password("defaultPassword")
                            .email("user" + collectionDto.getUserId() + "@example.com")
                            .nickname("用户" + collectionDto.getUserId())
                            .isEnabled(true)
                            .isLocked(false)
                            .build();
                    return userRepository.save(defaultUser);
                });
        
        // 检查是否已收藏
        if (isCollected(collectionDto.getUserId(), collectionDto.getContentType().name(), collectionDto.getContentId())) {
            throw new RuntimeException("Already collected");
        }
        
        Collection collection = Collection.builder()
                .user(user)
                .contentType(collectionDto.getContentType())
                .contentId(collectionDto.getContentId())
                .contentTitle(collectionDto.getContentTitle())
                .contentDescription(collectionDto.getContentDescription())
                .contentUrl(collectionDto.getContentUrl())
                .collectTime(LocalDateTime.now())
                .build();
        
        Collection savedCollection = collectionRepository.save(collection);
        return convertToDto(savedCollection);
    }
    
    @Override
    public void removeCollection(Long userId, String contentType, Long contentId) {
        Collection.ContentType type = Collection.ContentType.valueOf(contentType.toUpperCase());
        Collection collection = collectionRepository.findByUserIdAndContentTypeAndContentId(userId, type, contentId);
        if (collection != null) {
            collectionRepository.delete(collection);
        }
    }
    
    @Override
    public boolean isCollected(Long userId, String contentType, Long contentId) {
        Collection.ContentType type = Collection.ContentType.valueOf(contentType.toUpperCase());
        return collectionRepository.existsByUserIdAndContentTypeAndContentId(userId, type, contentId);
    }
    
    @Override
    public Page<CollectionDto> getUserCollections(Long userId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Page<Collection> collections = collectionRepository.findByUserIdOrderByCollectTimeDesc(userId, pageable);
        return collections.map(this::convertToDto);
    }
    
    @Override
    public Page<CollectionDto> getUserCollectionsByType(Long userId, String contentType, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Collection.ContentType type = Collection.ContentType.valueOf(contentType.toUpperCase());
        Page<Collection> collections = collectionRepository.findByUserIdAndContentTypeOrderByCollectTimeDesc(userId, type, pageable);
        return collections.map(this::convertToDto);
    }
    
    @Override
    public Page<CollectionDto> searchUserCollections(Long userId, String keyword, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Page<Collection> collections = collectionRepository.findByUserIdAndKeyword(userId, keyword, pageable);
        return collections.map(this::convertToDto);
    }
    
    @Override
    public void deleteCollection(Long collectionId) {
        collectionRepository.deleteById(collectionId);
    }
    
    @Override
    public void batchDeleteCollections(Long userId, Long[] collectionIds) {
        for (Long collectionId : collectionIds) {
            collectionRepository.deleteById(collectionId);
        }
    }
    
    @Override
    public void clearUserCollections(Long userId) {
        collectionRepository.deleteByUserId(userId);
    }
    
    @Override
    public void clearUserCollectionsByType(Long userId, String contentType) {
        Collection.ContentType type = Collection.ContentType.valueOf(contentType.toUpperCase());
        collectionRepository.deleteByUserIdAndContentType(userId, type);
    }
    
    private CollectionDto convertToDto(Collection collection) {
        return CollectionDto.builder()
                .id(collection.getId())
                .userId(collection.getUserId())
                .username(collection.getUser() != null ? collection.getUser().getUsername() : "Unknown")
                .contentType(collection.getContentType())
                .contentId(collection.getContentId())
                .contentTitle(collection.getContentTitle())
                .contentDescription(collection.getContentDescription())
                .contentUrl(collection.getContentUrl())
                .collectTime(collection.getCollectTime())
                .createdAt(collection.getCreatedAt())
                .build();
    }
}
